/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MIPS;

import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Keiner
 */
public class EtapaID extends Etapa {
    //public EtapaIF(int i, )

    private int[] juegoRegistros;
    private int PC = -1;
    private int[] IR;
    private int RA;
    private int RB;
    private int Inm;
    private boolean sigo = true;
    private boolean salto = false;
    private boolean falloIF = false;

    EtapaID(pizarra pizarraI, pizarra pizarraD, Semaphore semaphore, Semaphore principal, int[] registros) {
        super(1, pizarraI, pizarraD, semaphore, principal);
        juegoRegistros = registros;
    }

    public void setRegistros(int[] registros) {
        System.arraycopy(registros, 0, juegoRegistros, 0, registros.length);
    }

    @Override
    public void run() {
        while (true) {
            try {
                organizador.acquire();
                if (!atrasado) {
                    if (izquierda != null) {
                        synchronized (izquierda) {
                            izquierda.lock();
                            izquierda.setCopiado(true);
                            cambio = izquierda.getCambio();
                            if (cambio == false) {
                                sigo = true;
                            }
                            if (sigo) {
                                if (this.PC != izquierda.getPC() || cambio) {//caso que no hubo cambio de PC, asume fallo en IF
                                    falloIF = false;
                                    PC = izquierda.getPC();
                                    IR = izquierda.getIR();
                                    if (IR != null) {
                                        System.out.println("IR[0]: " + IR[0]);
                                    }
                                    /*resuelvo branchs*/
                                    if (IR != null && PC != -2) {
                                        if (IR[0] == 4 && IR[2] == 0) {//BEQZ Branch equal zero
                                            PC += 4;
                                            PC += (IR[3] * 4);
                                            salto = true;
                                            izquierda.setPC(PC);
                                        } else {
                                            if (IR[0] == 5 && IR[2] != 0) {//BNEZ Branch non equal zero
                                                PC += 4;
                                                PC += (IR[3] * 4);
                                                salto = true;
                                                izquierda.setPC(PC);
                                            } else {
                                                if (IR[0] == 2) {//JR Jump to Register
                                                    PC = juegoRegistros[IR[1]];
                                                    salto = true;
                                                    izquierda.setPC(PC);
                                                } else {
                                                    if (IR[0] == 3) {//JAL 
                                                        juegoRegistros[31] = PC;
                                                        PC = PC + IR[3];
                                                        salto = true;
                                                        izquierda.setPC(PC);
                                                    }
                                                }
                                            }
                                        }

                                    } else {
                                        falloIF = true;
                                    }
                                }
                            }
                            izquierda.unLock();
                        }

                        if (IR != null && sigo && !falloIF) {
                            RA = juegoRegistros[IR[1]];
                            RB = juegoRegistros[IR[2]];
                            Inm = IR[3];

                        }

                        if (derecha != null) {
                            esperar = true;
                            while (esperar) {
                                synchronized (derecha) {
                                    derecha.lock();
                                    if (derecha.getCopiado()) {
                                        esperar = false;
                                        if (sigo && IR != null && !falloIF) {
                                            if (!salto) {
                                                derecha.setImm(Inm);
                                                derecha.setRA(RA);
                                                derecha.setRB(RB);
                                                derecha.setPC(PC);
                                                derecha.setIR(IR);
                                                derecha.setCambio(cambio);
                                                derecha.setRL(juegoRegistros[31]);
                                            } else {
                                                salto = false;
                                            }
                                        }
                                    }
                                    derecha.unLock();
                                }
                            }
                        }
                        if (cambio) {
                            sigo = false;
                        }
                    }
                }
                principal.release();
                //    System.out.println("Saludos desde: " + quienSoy);
            } catch (InterruptedException ex) {
                Logger.getLogger(Etapa.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
